<?php

namespace App\Func\Office;

use PhpOffice\PhpWord\TemplateProcessor;
use setasign\Fpdi\Tcpdf\Fpdi as Fpdi;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
use TCPDF;
use Illuminate\Support\Facades\Storage;
// https://blog.csdn.net/lunarnan/article/details/116057896

class WordFunc
{
    /** 对word中的标识符进行替换，标识符的格式为 ${xx}
     * @param $tempUrl
     * @param array $replace 传入的数组，应包含特定的键和值类型
     *   - 'search' (string) - 需要替换的模版名称
     *   - 'replace' (string|array) - 要替换的内容
     *      - 'path' ('string') - 如果类型为2 则需要传入这些参数 图片路径
     *      - 'width' ('int') - 宽 单位像素
     *      - 'height' ('int') - 高 单位像素
     *   - 'type' (string) - 要替换的类型 1 字符串 2图片
     * @return string 替换后生成的文件路径
     * @throws \PhpOffice\PhpWord\Exception\CopyFileException
     * @throws \PhpOffice\PhpWord\Exception\CreateTemporaryFileException
     *
     */
    public function TemplateProcessorCustom($tempUrl, array $replace,string $outPutPath) : string
    {

//        dd((new WordFunc())->TemplateProcessorCustom(public_path() . '/xx.docx',[
//            [
//                'search' => 'zlh',
//                'type' => 2,
//                'replace' => [
//                    'path' => public_path().'/aaa.png',
//                    'width' => 50,
//                    'height' => 50
//                ],
//            ],
//            [
//                'search' => 'zlhxxxxx',
//                'type' => 1,
//                'replace' => "啊？",
//
//            ]
//        ]));
        // 读取现有的 Word 文档
        $tmp = new TemplateProcessor($tempUrl);
        foreach($replace as $value){
            if($value['type'] == 1){
                $tmp->setValue($value['search'], $value['replace']);
            }
            if($value['type'] == 2){
                $tmp->setImageValue($value['search'], $value['replace']);
            }
        }
        $tmp->saveAs($outPutPath);
        return $outPutPath;
    }

    /**
     * 协程化的方法
     * @param $tempUrl
     * @param array $replace
     * @param string $outPutPath
     * @return mixed
     * @throws \PhpOffice\PhpWord\Exception\CopyFileException
     * @throws \PhpOffice\PhpWord\Exception\CreateTemporaryFileException
     */
    public function TemplateProcessorCustomAsync($tempUrl, array $replace, string $outPutPath)
    {

        // 读取现有的 Word 文档
        $tmp = new TemplateProcessor($tempUrl);
        foreach ($replace as $value) {
            if ($value['type'] == 1) {
                $tmp->setValue($value['search'], $value['replace']);
            }
            if ($value['type'] == 2) {
                $tmp->setImageValue($value['search'], $value['replace']);
            }
        }
        $tmp->saveAs($outPutPath);
        return $outPutPath;

    }




    /**
     * word转pdf plus版本
     * @param $path
     * @param $outPutPath
     */
    public function wordConvertPdf($path,$outPutPath,$type = 1){
        // if($type == 1){
        //     $process = new Process(['docker','exec','u_c_1','unoconv','-f', 'pdf', '-o', $outPutPath, $path]);
        //     // $process = new Process(['unoconv','-p','50055', '-f', 'pdf', '-o', $outPutPath, $path]);
        // }else{
        //     $process = new Process(['docker','exec','u_c_2','unoconv','-f', 'pdf', '-o', $outPutPath, $path]);
        //     // $process = new Process(['unoconv','-p','50056', '-f', 'pdf', '-o', $outPutPath, $path]);
        // }
        $process = new Process(['docker','exec','u_c_'.$type,'unoconv','-f', 'pdf', '-o', $outPutPath, $path]);
        try {
            $process->run();
            $r = $process->getOutput();

            if (!$process->isSuccessful()) {
                var_dump('Word to PDF conversion failed: ' . $process->getErrorOutput());
                // 可以在这里添加重试逻辑
            }
        } catch (\Exception $e) {
            var_dump('Exception during Word to PDF conversion: ' . $e->getMessage());
        }

        return c_return([
            'savePath' => $outPutPath
        ], trans('message.file_cover_ok'))->content();
    }

    /**
     * 为当前pdf添加水印
     * @param $path
     * @param $outPutPath
     * @param $waterImagePath
     * @param $fileName
     * @throws \setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException
     * @throws \setasign\Fpdi\PdfParser\Filter\FilterException
     * @throws \setasign\Fpdi\PdfParser\PdfParserException
     * @throws \setasign\Fpdi\PdfParser\Type\PdfTypeException
     * @throws \setasign\Fpdi\PdfReader\PdfReaderException
     */
    public function pdfCoverWatermark($path,$outPutPath,$fileName,$waterImagePath){
        if(pathinfo($path)['extension']!='pdf'){
            fail_return(null,trans('message.upload_err',[
                'name'=>trans('key.can_file_type',[
                    'name' => 'pdf'
                ]),
                'code' => ''
            ]))->content();
        }
        $pdf = new Fpdi();
        // 为当前PDF添加水印
        $pageCount = $pdf->setSourceFile($path);
        //遍历所有页面
        for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++){
            //导入页面
            $templateId = $pdf->importPage($pageNo);
            //获取导入页面的大小
            $size = $pdf->getTemplateSize($templateId);
            //创建页面（横向或纵向取决于导入的页面大小）
            if ($size['width'] > $size['height']){
                $pdf->AddPage('L', array($size['width'], $size['height']));
            }else {
                $pdf->AddPage('P', array($size['width'], $size['height']));
            }
            //使用导入的页面
            $pdf->useTemplate($templateId);
            $pdf->image($waterImagePath, 0, 0,$size['width'],$size['height']);//全屏背景水印
        }
        // 输出pdf
        // I输出output，D下载download，F保存file_put_contents，S返回return
        $pdfReqName = $fileName.'_watermark.pdf';
        $p = Storage::path($outPutPath.DIRECTORY_SEPARATOR.$pdfReqName);
        $pdf->Output($p,'F');
        return c_return([
            'savePath' => $p
        ],trans('message.file_add_watermark_ok'))->content();
    }

    /**
     * 为当前pdf添加签名 暂时先不用这个方法
     * @param $path
     * @param $outPutPath
     * @return mixed
     * @throws \setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException
     * @throws \setasign\Fpdi\PdfParser\Filter\FilterException
     * @throws \setasign\Fpdi\PdfParser\PdfParserException
     * @throws \setasign\Fpdi\PdfParser\Type\PdfTypeException
     * @throws \setasign\Fpdi\PdfReader\PdfReaderException
     */
    public function pdfCoverSign($path,$outPutPath){
        // 初始化FPDI
        $pdf = new Fpdi();

        // 设置PDF的来源
        $sourceFilePath = $path; // 替换为你的PDF文件路径
        $pageCount = $pdf->setSourceFile($sourceFilePath);

        // 导入所有页面
        for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
            $tplIdx = $pdf->importPage($pageNo);
            $size = $pdf->getTemplateSize($tplIdx);

            // 添加新页
            $pdf->AddPage($size['orientation'], $size);
            $pdf->useTemplate($tplIdx);
        }

        // 在此处设置文档属性和签名等信息
        $pdf->SetTitle('Signed PDF');

        // 证书文件和私钥文件路径
        $certificate = database_path('seeders').DIRECTORY_SEPARATOR.'System'.DIRECTORY_SEPARATOR."certificate.crt"; // 证书路径
        $private_key = database_path('seeders').DIRECTORY_SEPARATOR.'System'.DIRECTORY_SEPARATOR."private.key"; // 私钥路径

        // 设置文档的数字签名
        $pdf->setSignature(file_get_contents($certificate), file_get_contents($private_key));

        // 设置密码保护
        $userPassword = '123'; // 用户密码
        $ownerPassword = null; // 所有者密码（如果设置为null，则自动生成）
        $permissions = array('print', 'copy'); // 允许的操作
        $pdf->SetProtection($permissions, $userPassword, $ownerPassword);

        $pdf->Output($outPutPath, 'F');
        return $outPutPath;
    }

    /**
     * 传入PDF 转换成 pdf
     * @param $path string pdf url
     * @param $outPutPath string 保存的地址 url 文件夹
     * @param int $level 输出的图片清晰度等级 默认1级 1级100的参数 2级200的参数 3级300的参数
     */
    public function pdfCoverToJpg($path,$outPutPath,$level = 1){
        $size = $level * 100;
        if(pathinfo($path)['extension']!='pdf'){
            fail_return(null,trans('message.upload_err',[
                'name'=>trans('key.can_file_type',[
                    'name' => 'pdf'
                ]),
                'code' => ''
            ]))->content();
        }

        if(!is_dir($outPutPath)){
            mkdir($outPutPath);
        }
        // convert -density 100 g.pdf -background white -alpha remove -quality 100 output-%d.jpg
        // composite -dissolve 100% -gravity center img.png input.jpg output.jpg
        //
        $process = new Process(['convert','-density',$size,'-background','white','-alpha','remove',$path,$outPutPath."/output-%d.jpg"]);
        $process->run();
        if (!$process->isSuccessful()) {
            throw new ProcessFailedException($process);
        }
        return c_return([
            'savePath' => $outPutPath
        ],trans('message.file_cover_ok'))->content();
    }

    public function pdfCoverToJpgNotLevel($path,$dockerPath,$outPutPath,$dockerOutPutPath,$type){
        $size = 100;
        if(pathinfo($path)['extension']!='pdf'){
            fail_return(null,trans('message.upload_err',[
                'name'=>trans('key.can_file_type',[
                    'name' => 'pdf'
                ]),
                'code' => ''
            ]))->content();
        }
        // convert -density 100 g.pdf -background white -alpha remove -quality 100 output-%d.jpg
        // composite -dissolve 100% -gravity center img.png input.jpg output.jpg
        //
        // if($type){
        //     $process = new Process(['docker','exec','u_c_1','convert','-density',$size,'-background','white','-alpha','remove',$path,$outPutPath."/output-%d.jpg"]);
        // }else{
        //     $process = new Process(['docker','exec','u_c_2','convert','-density',$size,'-background','white','-alpha','remove',$path,$outPutPath."/output-%d.jpg"]);
        // }
        $process = new Process(['docker','exec','u_c_'.$type,'convert','-density',$size,'-background','white','-alpha','remove',$dockerPath,$dockerOutPutPath."/output-%d.jpg"]);
//        $process = new Process(['convert','-density',$size,'-background','white','-alpha','remove',$path,$outPutPath."/output-%d.jpg"]);
        $process->run();
        if (!$process->isSuccessful()) {
            throw new ProcessFailedException($process);
        }
        return c_return([
            'savePath' => $dockerOutPutPath
        ],trans('message.file_cover_ok'))->content();
    }

}
